package lumis.portal.service;

import lumis.portal.PortalException;
import lumis.portal.PortalObjectAlreadyExistsException;
import lumis.portal.PortalObjectNotFoundException;
import lumis.portal.UnexpectedException;
import lumis.portal.dao.*;
import lumis.portal.dao.jdbc.ITransactionJdbc;
import lumis.util.ITransaction;
import lumis.util.JdbcUtil;

import java.sql.*;
import java.util.Collection;

/**
 * {@link IServiceDao} JDBC implementation
 * @version $Revision: 7409 $ $Date: 2007-06-13 18:37:18 -0300 (Wed, 13 Jun 2007) $
 * @since 4.0.0
 */
public class ServiceDaoJdbc implements IServiceDao
{
	/*
	 * (non-Javadoc)
	 * 
	 * @see lumis.portal.dao.ServiceDAO#add()
	 */
	public void add(ServiceConfig serviceConfig, ITransaction daoTransaction) throws DaoException, PortalException
	{
		try
		{
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) daoTransaction;
			Connection connection = daoTransactionJdbc.getConnection();

			PreparedStatement statement = connection.prepareStatement("insert into lum_Service (serviceId, name, description, baseUrl, stringsUrlPrefix, image, definition, accessControlListId, isInstantiable) values(?,?,?,?,?,?,?,?,?)");

			statement.setString(1, serviceConfig.getId());
			statement.setString(2, serviceConfig.getName());
			statement.setString(3, serviceConfig.getDescription());
			statement.setString(4, serviceConfig.getBaseUrl());
			statement.setString(5, serviceConfig.getStringsUrlPrefix());
			statement.setString(6, serviceConfig.getImage());
			statement.setString(7, serviceConfig.getDefinition());
			statement.setString(8, serviceConfig.getAccessControlListId());
			statement.setBoolean(9, serviceConfig.isInstantiable());

			try
			{
				statement.executeUpdate();
			}
			catch (Exception e)
			{
				try
				{
					if (get(serviceConfig.getId(), daoTransactionJdbc) != null)
						throw new PortalObjectAlreadyExistsException("STR_RESOURCE_ALREADY_EXISTS;" + serviceConfig.getId(), e);
					else
						throw e;
				}
				catch (PortalObjectNotFoundException e1)
				{
					throw e;
				}
			}
			statement.close();
		}
		catch (DaoException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see lumis.portal.dao.IServiceDao#update
	 */
	public void update(ServiceConfig serviceConfig, ITransaction daoTransaction) throws DaoException, PortalException
	{
		try
		{

			// TODO: Marcelo: Update de ACL foi tirado temporariamente
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) daoTransaction;
			Connection connection = daoTransactionJdbc.getConnection();

			// first try to update
			PreparedStatement statement = connection.prepareStatement("update lum_Service set name=?, description=?, baseUrl=?, stringsUrlPrefix=?, image=?, definition=?, isInstantiable=? where serviceId=?");

			statement.setString(1, serviceConfig.getName());
			statement.setString(2, serviceConfig.getDescription());
			statement.setString(3, serviceConfig.getBaseUrl());
			statement.setString(4, serviceConfig.getStringsUrlPrefix());
			statement.setString(5, serviceConfig.getImage());
			statement.setString(6, serviceConfig.getDefinition());
			// statement.setString(7, serviceConfig.getAccessControlListId());
			statement.setBoolean(7, serviceConfig.isInstantiable());
			statement.setString(8, serviceConfig.getId());

			statement.executeUpdate();
			statement.close();
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see lumis.portal.dao.IServiceDao#get(java.lang.String)
	 */
	public ServiceConfig get(String serviceId, ITransaction daoTransaction) throws DaoException, PortalException
	{
		try
		{
			ServiceConfig serviceConfig = null;
			String strQuery = "SELECT definition, accessControlListId FROM lum_Service WHERE serviceId=?";

			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) daoTransaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement(strQuery);
			try
			{
				statement.setString(1, serviceId);
				ResultSet resultSet = statement.executeQuery();
				try
				{
					if (resultSet.next())
					{
						serviceConfig = new ServiceConfig();
						serviceConfig.setDefinition(resultSet.getString("definition"));
						serviceConfig.setAccessControlListId(resultSet.getString("accessControlListId"));
					}
				}
				finally
				{
					resultSet.close();
				}
			}
			finally
			{
				statement.close();
			}

			if (serviceConfig == null)
				throw new PortalObjectNotFoundException("STR_SERVICE_DOES_NOT_EXIST;" + serviceId);

			return serviceConfig;
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see lumis.portal.dao.IServiceDao#delete(java.lang.String)
	 */
	public boolean delete(String serviceId, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();

			PreparedStatement statement = connection.prepareStatement("delete from lum_Service where serviceId = ?");
			try
			{
				statement.setString(1, serviceId);
				return statement.executeUpdate() > 0;				
			}
			finally
			{
				statement.close();				
			}
		}
		catch (SQLException e)
		{
			throw new UnexpectedException(e);
		}
	}

	public Collection<String> getServicesIds(boolean getInstantiableServicesOnly, ITransaction transaction) throws DaoException, PortalException
	{
		try
		{
			// TODO filter this based on the user sessionID

			String query = "SELECT serviceId FROM lum_Service";
			
			if(getInstantiableServicesOnly)
				query += " where isInstantiable=1";

			ITransactionJdbc daoTransactionJdbc = (ITransactionJdbc) transaction;
			Connection connection = daoTransactionJdbc.getConnection();
			PreparedStatement statement = connection.prepareStatement(query);
			try
			{
				return JdbcUtil.fillListString(statement, "serviceId");
			}
			finally
			{
				statement.close();
			}
		}
		catch (PortalException e)
		{
			throw e;
		}
		catch (Exception e)
		{
			throw new UnexpectedException(e);
		}
	}
	
	public ServiceConfig getByBaseUrl(String baseUrl, ITransaction daoTransaction) throws DaoException, PortalException
	{
		throw new UnsupportedOperationException();
	}

	public void clearCache() throws PortalException
	{
	}
}
